<?php
/**
 * @copyright  Copyright  LexisNexis, a division of Reed Elsevier Inc. All rights reserved.
 */
namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;

class MonitorCommand extends Command {
    /**
     * 控制台命令名称
     *
     * @var string
     */
    protected $signature = 'queue:monitor';

    /**
     * 控制台命令描述
     *
     * @var string
     */
    protected $description = 'RabbitMQ Monitor';

    public function __construct() {
        parent::__construct();
    }

    /**
     * 执行控制台命令
     *
     * @return mixed
     */
    public function handle() {
        $this->info('begin.');

        //http://10.123.4.215:15672/api/queues/%2f/log_msg
        $vhost = env('MQ_VHOST');
        if ($vhost == '/') {
            $vhost = '%2f';
        }
        $url = "http://" . env('MQ_HOST') . ':15672/api/queues/' . $vhost . '/' . env('MQ_QUEUE');

        for ($i = 0; $i <= 60; $i++) {
            sleep(60 * 1);
            $result = false;
            try {
                $result = $this->httpGet($url, array(
                    CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
                    CURLOPT_USERPWD => env('MQ_USER') . ':' .env('MQ_PASS')
                ));
            } catch (\Exception $exception) {
                $this->info('result: ' . print_r($result, 1));
                $this->error('cannot connect to rabbitmq server.' . $exception->getMessage());
                $this->sendAlertEmail('PSS ALERT', 'cannot connect to rabbitmq server.' . $exception->getMessage());
                sleep(60 * 30);
                continue;
            }
            if (!$result) {
                $this->info('result: ' . print_r($result, 1));
                $this->error('cannot connect to rabbitmq server.');
                $this->sendAlertEmail('PSS ALERT', 'cannot connect to rabbitmq server.');
                sleep(60 * 30);
                continue;
            }
            $json = @json_decode($result, true);
            if (!$json) {
                $this->info('result: ' . print_r($result, 1));
                $this->error('cannot decode json string');
                continue;
            }
            if (!isset($json['messages_ready'])) {
                $this->error('no messages_ready.');
                continue;
            }

            $length = env('MQ_WARNING_LENGTH');
            $length = $length ? $length : 10000;
            if ($json['messages_ready'] > $length) {
                $this->error("Message Ready has overflowed: {$json['messages_ready']}.");
                $this->sendAlertEmail('PSS ALERT', "Message Ready has overflowed: {$json['messages_ready']}.");
                sleep(60 * 30);
                continue;
            }
        }

        $this->info('done.');
    }

    protected function httpGet($url, $options = array()) {
        $defaults = array(
            CURLOPT_HEADER => 0,
            CURLOPT_URL => $url,
            CURLOPT_FRESH_CONNECT => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_FORBID_REUSE => 1,
            CURLOPT_TIMEOUT => 4
        );

        $ch = curl_init();
        curl_setopt_array($ch, $defaults + $options);
        if (!$result = curl_exec($ch)) {
            return false;
        }
        curl_close($ch);

        return $result;
    }

    protected function sendAlertEmail($subject, $content) {
        $toMail  = explode(';', env('MAIL_TO_LIST'));
        $fromMail = env('MAIL_FROM_ADDRESS');

        Mail::raw($content, function ($message) use ($subject, $toMail, $fromMail) {
            $message->subject($subject);
            $message->to($toMail);
            $message->from($fromMail);
        });
    }
}